#pragma once
#include "Log.hpp"
#include <sys/epoll.h>

namespace EpollerModule
{
    const int defaultepfd = -1;
    const int size = 128;
    class Epoller
    {
    public:
        Epoller(int epfd = defaultepfd) : _epfd(epfd)
        {
        }

        void InitEpoller()
        {
            _epfd = epoll_create(size);
            if (_epfd < 0)
            {
                lg.LogMessage(Fatal, "epoll_create fail, %s : %d\n", strerror(errno), errno);
                exit(4);
            }
            lg.LogMessage(Info, "epoll_create success, epfd: %d\n", _epfd);
        }

        // epoll_event告诉内核我们要关心什么事件
        void AddEvents(int sockfd, uint32_t events)
        {
            struct epoll_event evt;
            evt.data.fd = sockfd; // 最后是设置给用户看的
            evt.events = events;
            int n = epoll_ctl(_epfd, EPOLL_CTL_ADD, sockfd, &evt);
            if (n < 0)
            {
                lg.LogMessage(Error, "epoll_ctl add error, %s : %d\n", strerror(errno), errno);
            }
        }

        void DelEvents(int sockfd)
        {
            int n = epoll_ctl(_epfd, EPOLL_CTL_DEL, sockfd, nullptr);
            if (n < 0)
            {
                lg.LogMessage(Error, "epoll_ctl del error, %s : %d\n", strerror(errno), errno);
            }
        }

        int Wait(struct epoll_event *revs, int maxevents, int timeout)
        {
            int n = ::epoll_wait(_epfd, revs, maxevents, timeout);
            return n;
        }

        ~Epoller()
        {
            if (_epfd >= 0)
            {
                close(_epfd);
            }
        }

    private:
        int _epfd;
    };
}
